package com.wu.controller;


import com.alibaba.dubbo.config.annotation.Reference;
import com.wu.pojo.bean.RangeBean;
import com.wu.pojo.po.orgPo.OrgBase;
import com.wu.pojo.res.Result;
import com.wu.pojo.dto.PaperDTO;
import com.wu.pojo.vo.DataVo;
import com.wu.service.CounterService;
import com.wu.service.OrgBaseService;
import com.wu.service.PaperService;
import com.wu.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.*;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import static com.wu.constants.Constants.BUSITYPE;
import static com.wu.constants.Constants.ORGAREA;
import static com.wu.constants.Constants.ORGTYPE;


/**
 * [答题接口功能]
 *
 * @Author : [wuzhengru]
 * @Version : [v1.0]
 * @Date : [2021/5/13 01:13]
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/data")
@Api(value = "数据处理接口", tags = "数据处理接口", description = "DataProcessController")
public class DataProcessController {

    @Reference
    private PaperService paperService;
    @Reference
    private OrgBaseService orgBaseService;
    @Reference
    private CounterService counterService;


    @RequiresRoles(value={"admin","user"},logical = Logical.OR)
    @RequiresAuthentication
    @ApiOperation("查看平均数据")
    @PostMapping("getIndexData")
    public Result dataAllPaper(@RequestBody PaperDTO paperDTO) {

        // 1、参数校验
        String userId = null;
        if (null != paperDTO.getToken() && !"".equals(paperDTO.getToken())) {
            try {
                userId = (String)JwtUtils.getClaimByToken(paperDTO.getToken()).get("userId");
            } catch (Exception e) {
                log.debug("token信息失效,userId提取失败",e);
                return Result.fail("token信息失效，请重新登录！");
            }
        }
        String remark = paperDTO.getRemark();
        if (remark == null || "".equals(remark)) {
            log.error("未选择指数模型");
            return Result.fail("未选择指数模型");
        }

        // 2、初始化参数
        // 可选 orgAddr : 按地区，busiType : 按行业，orgType : 按企业类型，userId : 用户查询使用
        // 必选 remark : 模型类型 1-运行指数
        DataVo dataVo = new DataVo();
        String flag = paperDTO.getFlag();
        String orgArea = null;
        // 获取企业信息，打印信息时需要
        OrgBase orgBase = orgBaseService.queryOrgByUserId(userId);
        if (ORGAREA.equals(flag)) { //按区域查询
            // 设置该用户区域
            orgArea = orgBase.getOrgAddr();
        }
        String busiType = null;
        if (BUSITYPE.equals(flag)) { //按行业查询
            // 设置该用户行业
            busiType = orgBase.getBusiType();
        }
        String orgType = null;
        if (ORGTYPE.equals(flag)) { //按企业类型查询
            // 设置该用户企业类型
            orgType = orgBase.getOrgType();
        }
        // 否则为DEFALUT

        // 3、查询数据

        // 拿到全部企业视图模型值
        dataVo.setOrgAddr(orgArea).setBusiType(busiType).setOrgType(orgType).setModelInfo(remark);
        List<DataVo> allDataVos = paperService.scoreCollect(dataVo);
        JSONObject avgObject = counterService.initData(allDataVos);

        // 拿到本企业视图模型值
        dataVo.setUserId(userId).setOrgAddr(orgArea).setBusiType(busiType).setOrgType(orgType).setModelInfo(remark);
        List<DataVo> myDataVos = paperService.scoreCollect(dataVo);
        JSONObject myObject = counterService.initData(myDataVos);


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("myObject", myObject);
        jsonObject.put("avgObject", avgObject);
        jsonObject.put("orgArea", orgBase.getOrgAddr());
        jsonObject.put("busiType", orgBase.getBusiType());
        jsonObject.put("orgType", orgBase.getOrgType());
        jsonObject.put("orgName", orgBase.getOrgName());

        return Result.succ(jsonObject);

    }

    @RequiresRoles("admin")
    @ApiOperation("完整报告（行业、企业类型、区域对应的数量、平均运行指数）")
    @GetMapping("getCompleteReport")
    public Result getCompleteReport() {
        // 查询所有区域
        List<String> areaList =  orgBaseService.selectAreaList();
        // 查询所有企业类型
        List<String> orgTypeList = orgBaseService.selectOrgTypeList();
        // 查询所有行业
        List<String> busiTypeList = orgBaseService.selectBusiTypeList();

        JSONObject jsonObject = new JSONObject();
        // 遍历区域，取得每个区域企业数量
        inorder(areaList,"area",jsonObject);
        // 遍历企业类型
        inorder(orgTypeList,"orgType",jsonObject);
        // 遍历行业
        inorder(busiTypeList,"busiType",jsonObject);

        return Result.succ(jsonObject);
    }

    @RequiresRoles(value={"admin","user"},logical = Logical.OR)
    @RequiresAuthentication
    @ApiOperation("分析运行指数")
    @PostMapping("getDataRank")
    public Result getDataRank(@RequestBody PaperDTO paperDTO) {

        // 1、参数校验
        String userId = null;
        if (null != paperDTO.getToken() && !"".equals(paperDTO.getToken())) { // 用户
            try {
                userId = (String)JwtUtils.getClaimByToken(paperDTO.getToken()).get("userId");
            } catch (Exception e) {
                return Result.fail("token已失效，请重新登录");
            }
        } else { // 管理员，只需要拿到各分段人数，不关注排名
            userId = "BCD7CCBC3C9D4209B9C35FE4D8E542D5";// 赋值默认用户即可
        }

        // 预处理
        RangeBean rangeBean = new RangeBean();

        Map userRankByOrgType = this.rangeByCondition("ORGTYPE", userId, rangeBean);
        Map userRankByBusiType = this.rangeByCondition("BUSITYPE", userId, rangeBean);
        Map userRankByOrgArea = this.rangeByCondition("ORGAREA", userId, rangeBean);
        Map userRank = this.rangeByCondition("DEFAULT", userId, rangeBean);

        // 赋值
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userRankByOrgType", userRankByOrgType.get("rank"));// 企业类型排名
        jsonObject.put("userRankByBusiType", userRankByBusiType.get("rank"));// 行业排名
        jsonObject.put("userRankByOrgArea", userRankByOrgArea.get("rank"));// 区域排名
        jsonObject.put("userRank", userRank.get("rank"));// 总排名
        jsonObject.put("jsonObjectOrgType", userRankByOrgType.get("jsonObject"));// 机构类型人数
        jsonObject.put("jsonObjectBusiType", userRankByBusiType.get("jsonObject"));// 行业人数
        jsonObject.put("jsonObjectOrgArea", userRankByOrgArea.get("jsonObject"));// 区域人数
        jsonObject.put("jsonObjectUser", userRank.get("jsonObject"));// 总人数

        return Result.succ(jsonObject);
    }

    /**
     * 查询各分段、各（行业、区域、企业类型）企业数量
     */
    private Map<String, Object> rangeByCondition(String flag, String userId, RangeBean rangeBean) {
        DataVo dataVo = new DataVo();
//        userId="BCD7CCBC3C9D4209B9C35FE4D8E542D5";// 测试
        DataVo userdataVo = counterService.dataRankByUserId(userId);// 获得用户排名
        OrgBase orgBase = orgBaseService.queryOrgByUserId(userId);// 获取用户机构信息，取得对应机构行业、机构类型、机构区域

        List<DataVo> dataVos = null;// 指数排行列表
        int userRank = 0;// 用户名次
        int totalRank = 0;// 总数
        Map<String, Object> map = null;

        switch (flag) {
            case ORGAREA:
                dataVo.setOrgAddr(orgBase.getOrgAddr());
                // 根据区域查询运行指数排行榜
                dataVos = counterService.dataRank(dataVo);
                // 预处理
                totalRank = dataVos.size();// 总用户
                // 获取排名，此时只关注排名，获取分值区域范围数量注入rangeBean中
                userRank = this.getRank(dataVos, userdataVo, rangeBean);
                map = new HashMap<>();
                JSONObject rankRange = getRankRange(rangeBean);
                map.put("jsonObject",rankRange);
                map.put("rank",userRank + "/" + totalRank);
                return map;
            case BUSITYPE:
                dataVo.setBusiType(orgBase.getBusiType());
                // 根据行业类查询运行指数排行榜
                dataVos = counterService.dataRank(dataVo);
                // 预处理
                totalRank = dataVos.size();// 总用户
                // 获取排名
                userRank = this.getRank(dataVos, userdataVo, rangeBean);

                map = new HashMap<>();
                map.put("jsonObject",getRankRange(rangeBean));
                map.put("rank",userRank + "/" + totalRank);
                return map;
            case ORGTYPE:
                dataVo.setOrgType(orgBase.getOrgType());
                // 根据企业类型查询运行指数排行榜
                dataVos = counterService.dataRank(dataVo);
                // 预处理
                totalRank = dataVos.size();// 总用户
                // 获取排名
                userRank = this.getRank(dataVos, userdataVo, rangeBean);
                map = new HashMap<>();

                map.put("jsonObject",getRankRange(rangeBean));
                map.put("rank",userRank + "/" + totalRank);
                return map;
            default:
                // 查询全部运行指数排行榜
                dataVos = counterService.dataRank(dataVo);
                // 预处理
                totalRank = dataVos.size();// 总用户
                userRank = this.getRank(dataVos, userdataVo, rangeBean);

                map = new HashMap<>();

                map.put("jsonObject",getRankRange(rangeBean));
                map.put("rank",userRank + "/" + totalRank);
                return map;
        }
    }

    /**
     * 查询名次，注入bean
     */
    private int getRank(List<DataVo> dataVos, DataVo userdataVo, RangeBean rangeBean) {
        int userRank = 0;// 用户名次
        for (int i = 0; i < dataVos.size(); i++) { //dataVos，按积分排序
            DataVo dataVo1 = dataVos.get(i);
            double runningIndex = dataVo1.getRunningIndex();
            this.rangeCal(runningIndex, rangeBean);
            if (userdataVo.getRunningIndex() == runningIndex) {
                userRank = i + 1;// 取得当前下表值，则为此用户名次
            }
        }
        return userRank;
    }

    /**
     * 预处理
     */
    private void rangeCal(double runningIndex, RangeBean rangeBean) {
        if (rangeBean == null) {
            return;
        }
        //预处理
        int res = 0;
        if (runningIndex >= 0 && runningIndex <= 30) {
            res = 1;
        } else if (runningIndex >= 56 && runningIndex <= 75) {
            res = 98;
        } else if (runningIndex >= 75 && runningIndex <= 100) {
            res = 99;
        } else {
            int runningIndexInt = (int) runningIndex;
            res = runningIndexInt / 5;
        }

        //执行
        switch (res) {
            //低分，高分range
            case 1:
                rangeBean.setRange0_30(rangeBean.getRange0_30() + 1);
                break;
            case 98:
                rangeBean.setRange56_75(rangeBean.getRange56_75() + 1);
                break;
            case 99:
                rangeBean.setRange76_100(rangeBean.getRange76_100() + 1);
                break;

            //以5为阶段为分界得range
            case 6:
                rangeBean.setRange31_35(rangeBean.getRange31_35() + 1);
                break;
            case 7:
                rangeBean.setRange36_40(rangeBean.getRange36_40() + 1);
                break;
            case 8:
                rangeBean.setRange41_45(rangeBean.getRange41_45() + 1);
                break;
            case 9:
                rangeBean.setRange46_50(rangeBean.getRange46_50() + 1);
                break;
            case 10:
                rangeBean.setRange51_55(rangeBean.getRange51_55() + 1);
                break;
        }
    }

    /**
     * 分值范围企业数量注入bean
     */
    private JSONObject getRankRange(RangeBean rangeBean) { // 分类时通过注入新的rangeBean获取对应条件企业数量列表
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("range0_30", rangeBean.getRange0_30());
        jsonObject.put("range31_35", rangeBean.getRange31_35());
        jsonObject.put("range36_40", rangeBean.getRange36_40());
        jsonObject.put("range41_45", rangeBean.getRange41_45());
        jsonObject.put("range46_50", rangeBean.getRange46_50());
        jsonObject.put("range51_55", rangeBean.getRange51_55());
        jsonObject.put("range56_75", rangeBean.getRange56_75());
        jsonObject.put("range76_100", rangeBean.getRange76_100());
        return jsonObject;
    }

    /**
     *  遍历赋值
     *  @param list 赋值列表
     *  @param type 赋值类型
     *  @param jsonObject 返回前端json
     */
    private void inorder(List<String> list,String type,JSONObject jsonObject) {
        JSONArray jsonArray = new JSONArray();
        for (String remark : list) {
            // 查询对应type的总数量和平均值
            DataVo completeData = orgBaseService.selectCompleteData(remark,type);
            // 赋值
            Map<String,Object> map = new LinkedHashMap<>();
            map.put(String.format("%s企业数量",remark),completeData.getCountAnswer());
            // 保留两位小数
            if (completeData.getAvgScore() != 0) {
                DecimalFormat df = new DecimalFormat("#.00");
                String avgScoreF = df.format(completeData.getAvgScore());
                map.put("运行指数平均值", avgScoreF);
            } else {
                map.put("运行指数平均值",completeData.getAvgScore());
            }
            jsonArray.add(map);
        }
        jsonObject.put(type,jsonArray);
    }
}
